package vno.fux.init
{
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.ProgressEvent;
	import flash.events.TimerEvent;
	import flash.media.Sound;
	import flash.system.System;
	import flash.utils.Timer;
	import flash.utils.setTimeout;
	
	import vno.fux.BasePoint;
	import vno.fux.CompassDirection;
	import vno.fux.GlobalEventScheduler;
	import vno.fux.GlobalVar;
	import vno.fux.character.CharacterLayer;
	import vno.fux.map.MapLayer;
	import vno.fux.mediator.LayerMediator;
	import vno.fux.move.MoveSystem;
	import vno.fux.res.manager.CommonLoader;
	import vno.fux.res.manager.LoaderManager;
	import vno.fux.res.manager.ResourceManager;
	import vno.fux.res.manager.ResourceMission;
	import vno.fux.res.pool.ConfigPool;
	import vno.fux.res.pool.ResourceInventory;
	import vno.fux.res.pool.ResourcePool;
	import vno.fux.res.pool.SoundResource;
	import vno.fux.res.pool.SoundTarget;
	import vno.fux.res.pool.XMLTarget;
	import vno.fux.task.TaskSystem;
	import vno.fux.ui.UiLayer;
	import vno.fux.utils.DynamicMission;
	import vno.fux.utils.Mission;
	import vno.fux.utils.MissionManager;
	import vno.sci.Util;
	import vno.sci.window.UILayer;


	public class Initer extends EventDispatcher
	{
		private static var instance:Initer;
		private var _initInfo:XMLTarget;
		private var _resourceManager:ResourceManager;
		private var _resourcePool:ResourcePool;
		private var _configPool:ConfigPool;
		private var _missionManager:MissionManager;
		private var _ml:MapLayer;
		private var _cl:CharacterLayer;
		private var _ul:UiLayer;
		private var _root:Sprite;
		private var _loadingInterface:LoadingInterface;
		private var _mapInfo:XML;
		private var _resInfo:XML;

		public function Initer(pvt:PrivateClass, root_:Sprite)
		{
			_root = root_;
		}
		public function init():void
		{
			initPrepare();
		}
		private function initPrepare():void
		{
			GlobalEventScheduler.init(_root.stage);

			_missionManager = new MissionManager;
			
			ConfigPool.init();
			_configPool = ConfigPool.getInstance();

			loadInitConfig();
		}

		private function loadInitConfig():void
		{
			var tmpLoader:LoaderManager = new LoaderManager(1);
			tmpLoader.addEventListener(tmpLoader.getCurrentMissionCompleteEvent(), initLoadingInterface);
			_initInfo = new XMLTarget;
			tmpLoader.addMission(new ResourceMission(GlobalVar.webUrl+"VNO/Configs/InitConfig.xml", _initInfo, CommonLoader.XML));
		}

		private function initLoadingInterface(event:Event):void
		{
			(event.target as LoaderManager).removeEventListener(event.type, initLoadingInterface);
			var setting:XML = _initInfo.xml.loadingInterface[0];
			_loadingInterface = new LoadingInterface(setting);
			_missionManager.addEventListener(ProgressEvent.PROGRESS, _loadingInterface.handleProgress);
			_loadingInterface.addEventListener(Event.COMPLETE, startLoad);
		}

		private function startLoad(event:Event):void
		{
			_loadingInterface.removeEventListener(Event.COMPLETE, startLoad);
			_root.stage.addChild(_loadingInterface);


			_missionManager.addMission(
				new Mission(_configPool.initConfigs, null, _configPool, ProgressEvent.PROGRESS, Event.COMPLETE, "Load Configs"));
			_missionManager.addMission(
				new Mission(baseInit, null, null, null, null, "Core Class Init"));
			_missionManager.addMission(
				new Mission(mapResourceLoad, null, null, null, null, "MapResource Load Init"));
			_missionManager.addMission(
				new Mission(soundResourceLoad, null, null, null, null, "SoundResource Load Init"));
			_missionManager.addMission(
				new Mission(_loadingInterface.userInit, null, _loadingInterface, null, Event.COMPLETE, "User Choosing"));
			_missionManager.addMission(
				new Mission(characterResourceLoad, null, null, null, null, "CharacterResource Load Init"));			
			_missionManager.addMission(
				new Mission(uiResourceLoad, null, null, null, null, "UiResource LoadInit"));
			_missionManager.addEventListener(Event.COMPLETE, delayStart);
			_missionManager.run();
		}

		private function baseInit():void
		{
			_mapInfo = _configPool.getXMLConfig("mapConfig");
			_resInfo = _configPool.getXMLConfig("resourceConfig");

			ResourcePool.init(_resInfo);
			_resourcePool = ResourcePool.getInstance();

			ResourceManager.init(_resInfo);
			_resourceManager = ResourceManager.getInstance();

			TaskSystem.init(_configPool.getTextConfig("taskConfig"));
			MoveSystem.init(_configPool.getBinaryData("m11access"));
			
			var initRI:ResourceInventory = getIniRi();
			_resourcePool.setCurrentInventory(0);
		}

		private function mapResourceLoad():void
		{
			_missionManager.addMission(new DynamicMission
				(_resourceManager.map.loadThumbMap, _initInfo.xml.mapid, _resourceManager.loader, _resourceManager.loader,"Load ThumbMap"));

		}
		private function soundResourceLoad():void
		{
			_missionManager.addMission(new DynamicMission
				(_resourceManager.snd.load, 0, _resourceManager.loader, _resourceManager.loader,"Load MainBGM"));
		}
		
		private function uiResourceLoad():void
		{
			_missionManager.addMission(new DynamicMission
				(_resourceManager.ui.load, 0, _resourceManager.loader, _resourceManager.loader,"Load Arrow"));
			_missionManager.addMission(new DynamicMission
				(_resourceManager.ui.load, 1, _resourceManager.loader, _resourceManager.loader,"Load BGMButton"));
			_missionManager.addMission(new DynamicMission
				(_resourceManager.ui.load, 2, _resourceManager.loader, _resourceManager.loader,"Load MinimapBorder"));
			_missionManager.addMission(new DynamicMission
				(_resourceManager.cha.load, 999999, _resourceManager.loader, _resourceManager.loader, "Load Building Point"));
		}
		
		private function characterResourceLoad():void
		{
			_missionManager.addMission(new DynamicMission
				(_resourceManager.cha.load, _loadingInterface.userChoose==1?0:1, _resourceManager.loader, _resourceManager.loader, "Load Player"));
		}

		private function delayStart(event:Event):void
		{
			var myTimer:Timer = new Timer(500, 1);
			myTimer.addEventListener(TimerEvent.TIMER, loadCompleteHandler);
			myTimer.start();
		}
		
		private function loadCompleteHandler(event:TimerEvent):void
		{
			//trace(Util.markerToArray(ConfigPool.getInstance().getBinaryData("m11building")));
			(event.target as Timer).stop();
			(event.target as Timer).removeEventListener(TimerEvent.TIMER, loadCompleteHandler);
			//trace(Util.markerToArray(ConfigPool.getInstance().getBinaryData("m11building")));
			_missionManager.removeEventListener(ProgressEvent.PROGRESS, _loadingInterface.handleProgress);
			_missionManager = null;
			var userSex:int = _loadingInterface.userChoose;
			GlobalEventScheduler.getInstance().addEnterFrameListener(loadingInterfaceDisapear);
			mediatorInit();
			mapLayerInit();
			characterLayerInit();
			uiLayerInit();
			
			switch(userSex)
			{
				case 0:
					TaskSystem.getInstance().switchOn(99);
					_cl.setMainPlayer(1, 1, CompassDirection.S);
					break;
				case 1:
					_cl.setMainPlayer(0, 0, CompassDirection.S);
					break;
			}

			_ml.setCoordinate(new BasePoint(_initInfo.xml.birthPlace.@x, _initInfo.xml.birthPlace.@y));
		}
		
		private function loadingInterfaceDisapear(event:Event):void
		{
			var tmp:Number = _loadingInterface.alpha;
			tmp-=0.01;
			if(tmp<0)
			{
				GlobalEventScheduler.getInstance().removeEnterFrameListener(loadingInterfaceDisapear);
				_root.stage.removeChild(_loadingInterface);
				_loadingInterface = null;
				return;
			}
			_loadingInterface.alpha = tmp;
		}
		
		private function getIniRi():ResourceInventory
		{
			var tmp:ResourceInventory = new ResourceInventory(0);
			tmp.map.add(_initInfo.xml.mapid);
			tmp.character.add(0);
			tmp.character.add(1);
			for(var i:int = 100000; i<=100063; i++)
			{
				tmp.character.add(i);
			}
			tmp.character.add(999999);
			tmp.ui.add(0);
			tmp.ui.add(1);
			tmp.ui.add(2);
			tmp.snd.add(0);
			return tmp;
		}
		
		private function mediatorInit():void
		{
			LayerMediator.init();
		}
		
		private function uiLayerInit():void
		{
			_ul = new UiLayer(/*_info*/);
			TaskSystem.getInstance().setUi(_ul);
			// _ul.x = _root.stage.stageWidth/2;
			// _ul.y = _root.stage.stageHeight/2;
			_root.addChild(_ul);
			LayerMediator.getInstance().uiLayer = _ul;
		}
		
		private function characterLayerInit():void
		{
			_cl = new CharacterLayer(characterInfoConvert(_mapInfo));
			_cl.create(_initInfo.xml.mapid);
			_cl.x = _root.stage.stageWidth/2;
			_cl.y = _root.stage.stageHeight/2;
			LayerMediator.getInstance().characterLayer = _cl;
			_root.addChild(_cl);
		}

		private function characterInfoConvert(resourse:XML):XML//code by ky
		{
			var setting:XML=<character/>;
			for(var i:int =0;resourse.map[i]!=null;i++)
			{
				setting.appendChild(<map/>);
				setting.map[i].@id = resourse.map[i].@id;
				setting.map[i].appendChild(<playerLayer/>);
				setting.map[i].playerLayer[i]=resourse.map[i].character.playerLayer;
				setting.map[i].appendChild(<npcLayer/>);
				setting.map[i].npcLayer[i]=resourse.map[i].character.npcLayer;
			}
			return setting;
		}
		
		private function mapLayerInit():void
		{
			// TODO Auto Generated method stub

			_ml = new MapLayer(mapInfoConvert(_mapInfo));
			_ml.create(_initInfo.xml.mapid);
			_ml.x = _root.stage.stageWidth/2;
			_ml.y = _root.stage.stageHeight/2;
			//MoveSystem.getInstance().mapLayer = _ml;
			LayerMediator.getInstance().mapLayer = _ml;
			_root.addChild(_ml);
		}
		private function mapInfoConvert(resourse:XML):XML//code by ky
		{
			var setting:XML=<settings/>;
			for(var i:int =0;resourse.map[i]!=null;i++)
			{
				setting.appendChild(<map/>);
				setting.map[i].@id=resourse.map[i].@id;
				setting.map[i].@resId=resourse.map[i].@resId;
				setting.map[i].@width=resourse.map[i].@width;
				setting.map[i].@height=resourse.map[i].@height;
				setting.map[i].@moveSpeed=resourse.map[i].@moveSpeed;
				setting.map[i].appendChild(<tiles/>);
				setting.map[i].tiles=resourse.map[i].tiles;	
				setting.map[i].appendChild(<grid/>);
				setting.map[i].grid=resourse.map[i].grid;
			}
			return setting;
		}
		
		private function resizeHandler(evt:Event):void
		{
			_ml.x = _root.stage.stageWidth/2;
			_ml.y = _root.stage.stageHeight/2;
			_cl.x = _root.stage.stageWidth/2;
			_cl.y = _root.stage.stageHeight/2;
			// _ul.x = _root.stage.stageWidth/2;
			// _ul.y = _root.stage.stageHeight/2;
		}

		public static function init(info:XML, root_:Sprite):void
		{
			if(Initer.instance)
			{
				throw new Error("You can't init the Initer twice!")
			}
			Initer.instance = new Initer(new PrivateClass, root_);
		}
		public static function getInstance():Initer
		{
			return Initer.instance;
		}
		
	}
}
class PrivateClass
{
	public function PrivateClass()
	{
	}
}